﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EasyOAuth.Core.Encrypt;
using EasyOAuth.Core.Configuration;

namespace EasyOAuth.Core.OAuth
{
    /// <summary>
    /// 访问令牌
    /// </summary>
    public class AccessTokenBuilder
    {
        /// <summary>
        /// token过期时间 默认 2小时 单位秒
        /// </summary>
        public int ExpireTime { get; private set; } = AppConfig.Get<int>("AccessTokenExpireTime");

        /// <summary>
        /// 加密的密钥 默认读配置文件 Dynamic.Token.Key 节点内容
        /// </summary>
        public string EncryptKey { get; private set; } = AppConfig.Get<string>("AccessTokenEncryptKey");

        /// <summary>
        /// 动态令牌生成器 不会储存在缓存中
        /// </summary>
        public AccessTokenBuilder() { }

        /// <summary>
        /// 动态令牌生成器 不会储存在缓存中
        /// </summary>
        /// <param name="encryptKey">加密key</param>
        /// <param name="expireTime">过期时间 单位秒</param>
        public AccessTokenBuilder(string encryptKey, int expireTime = 7200)
        {
            EncryptKey = encryptKey;
            ExpireTime = expireTime;
        }

        /// <summary>
        /// 创建token
        /// </summary>
        /// <param name="storeData">储存自定义数据</param>
        /// <returns></returns>
        public string Create(Dictionary<string, string> storeData)
        {

            var guid = Guid.NewGuid().ToString("n");
            var accessTokenKeys = new AccessTokenKeys
            {
                G = guid,
                E = DateTime.Now.AddSeconds(ExpireTime).ToUnixTimeStamp(),
                D = storeData
            }.ToJson();

            return AESEncrypt.Encrypt(accessTokenKeys, EncryptKey);
        }

        /// <summary>
        /// 获取储存自定义数据
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetStoreData(string token)
        {
            var rawData = AESEncrypt.Decrypt(token, EncryptKey);

            var d = JObject.Parse(rawData)["D"]?.ToString();

            if (string.IsNullOrWhiteSpace(d)) 
            {
                return new Dictionary<string, string>();
            }

            return d.JsonToObject<Dictionary<string, string>>();
        }

        /// <summary>
        /// 验证token是否有效
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool Validate(string token)
        {
            try
            {
                var rawData = AESEncrypt.Decrypt(token, EncryptKey);
                var expiresDate = Convert.ToInt64(JObject.Parse(rawData)["E"]);
                var nowDate = DateTime.Now.ToUnixTimeStamp();
                return expiresDate > nowDate;
            }
            catch (Exception)
            {
                return false;
            }

        }
    }

    /// <summary>
    /// 生成储存的数据key
    /// </summary>
    public class AccessTokenKeys
    {
        /// <summary>
        /// 唯一ID
        /// </summary>
        public string G { get; set; } = string.Empty;

        /// <summary>
        /// 过期时间
        /// </summary>
        public long E { get; set; } = 0;

        /// <summary>
        /// 储存的数据
        /// </summary>
        public Dictionary<string, string> D { get; set; } = new Dictionary<string, string>();
    }
}
